Skip to content

[CTL] Add support for defaults #1320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

KFilipek
Copy link
Contributor

@KFilipek KFilipek commented May 19, 2025

Description

Checklist

  • Code compiles without errors locally
  • All tests pass locally
  • CI workflows execute properly

@KFilipek KFilipek self-assigned this May 19, 2025
@KFilipek KFilipek requested a review from a team as a code owner May 19, 2025 09:01
@KFilipek KFilipek added the enhancement New feature or request label May 19, 2025
@bratpiorka bratpiorka requested review from lplewa and bratpiorka May 19, 2025 09:28
umfDisjointPoolParamsDestroy(params);
} catch (Pool::CtlException &e) {
umfDisjointPoolParamsDestroy(params);
GTEST_SKIP() << e.what();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why skip, can't we fail?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach is commonly used in our tests:

ctest --verbose | grep SKIP | wc -l
295

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in some cases SKIP is acceptable, here I believe occurence of CtlException may be caused by a real issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed CtlException completely

umf_memory_provider_handle_t provider_handle = nullptr;
umf_memory_pool_handle_t pool = NULL;

struct memory_provider : public umf_test::provider_base_t {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this struct in this test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reworked separately. It follows the approach used in the disjoint pool tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so pls leave the struct but don't add the dead code which is the body of the struct with redundant functions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed boilerplate.

auto res = umfPoolCreate(m_poolOps, m_provider, m_params, 0, &m_pool);
if (res != UMF_RESULT_SUCCESS) {
m_pool = nullptr;
LOG_ERR("Failed to create memory pool");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if LOG in test is expected

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.
Removed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, if you still want to print some error msg in tests you can just use printf or something..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe unit tests should not print logs.

src/libumf.c Outdated
Comment on lines 101 to 135

umf_result_t umfCtlGet(const char *name, void *ctx, void *arg, size_t size) {
if (name == NULL || arg == NULL) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_READ,
arg, size);
}

umf_result_t umfCtlSet(const char *name, void *ctx, void *arg, size_t size) {
// Context can be NULL when setting defaults
if (name == NULL || arg == NULL || size == 0) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_WRITE,
arg, size)
? UMF_RESULT_ERROR_UNKNOWN
: UMF_RESULT_SUCCESS;
}

umf_result_t umfCtlExec(const char *name, void *ctx, void *arg, size_t size) {
if (name == NULL || arg == NULL || ctx == NULL) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name,
CTL_QUERY_RUNNABLE, arg, size)
? UMF_RESULT_ERROR_UNKNOWN
: UMF_RESULT_SUCCESS;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is chaos in this inval check - please add comment per each function why we not check for null.

For sure exec should accept null arg.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 62 to 60
if (ctx && strstr(extra_name, "default")) {
utils_mutex_unlock(&ctl_mtx);
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this strstr? If yes what we are looking for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -22,13 +22,13 @@
#include "utils_assert.h"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is support for defaults for memory providers? I see only implementation for pools, and we need both

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be splitted between 2 PR's

Comment on lines 147 to 155
/// @brief Retrieves the name of the disjoint memory pool [optional]
/// @param pool pointer to the memory pool or NULL value
/// @return A constant character string representing the pool's name.
/// Returns "disjoint" if `pool` is NULL, otherwise returns the
/// configured name of the specific pool instance.
///
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document requirements of interface - not how this function behaviors for disjoint pool

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

src/ctl/ctl.h Outdated
Comment on lines 191 to 202
/*
* Declaration of a new RW leaf. This type of RW leaf doesn't require parsing
* of the argument. The argument is passed directly to the read/write callback.
*/
#define CTL_LEAF_RW_no_arg(name, ...) \
{ \
CTL_STR(name), CTL_NODE_LEAF, \
{CTL_READ_HANDLER(name, __VA_ARGS__), \
CTL_WRITE_HANDLER(name, __VA_ARGS__), NULL, NULL}, \
NULL, NULL \
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, done.

@@ -21,35 +21,35 @@ TEST_F(test, ctl_debug_read_from_string) {

int value = 0;
ctl_query(ctl_handler, NULL, CTL_QUERY_PROGRAMMATIC,
"debug.heap.alloc_pattern", CTL_QUERY_READ, &value);
"debug.heap.alloc_pattern", CTL_QUERY_READ, &value, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my comment from the prev. PR is not resolved:

whenever size is used, please add a test with various values (user may give some input we may not expect, e.g. on wrong assumptions on how this func works) or mark a TODO for adding tests in the future

e.g. here you can simply add a repeated queries with non-zero values

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@KFilipek KFilipek force-pushed the ctl-default branch 6 times, most recently from 3dbf762 to c43ddc7 Compare May 22, 2025 14:37
@KFilipek KFilipek force-pushed the ctl-default branch 6 times, most recently from aec5266 to fe4e66f Compare May 23, 2025 08:14
///
/// @brief Retrieve name of a given memory \p pool.
/// @param pool handle to the memory pool
/// @return pointer to a string containing the name of the \p pool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

, or NULL when ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/// @param operationType type of the operation to be performed.
/// @param name name associated with the operation.
/// @param arg argument for the operation.
/// @param size size of the argument [optional - check path requirements]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant english word "context" not a parameter called context; nontheless, IMHO, this is still ambiguous - I'm really not sure what/where should I check

@@ -259,12 +259,13 @@ typedef struct umf_memory_provider_ops_t {
/// @param operationType type of the operation to be performed.
/// @param name name associated with the operation.
/// @param arg argument for the operation.
/// @param size size of the argument [optional - check path requirements]
/// @param queryType type of the query to be performed.
///
/// @return umf_result_t result of the control operation.
///
umf_result_t (*ctl)(void *hProvider, int operationType, const char *name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a few lines above in the review we can see the change hPool -> pool; similarly here hProvider -> provider

// it's just a nit

umfDisjointPoolParamsDestroy(params);
} catch (Pool::CtlException &e) {
umfDisjointPoolParamsDestroy(params);
GTEST_SKIP() << e.what();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in some cases SKIP is acceptable, here I believe occurence of CtlException may be caused by a real issue

umf_memory_provider_handle_t provider_handle = nullptr;
umf_memory_pool_handle_t pool = NULL;

struct memory_provider : public umf_test::provider_base_t {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so pls leave the struct but don't add the dead code which is the body of the struct with redundant functions

// umfCtlGet - invalid arg
res = umfCtlGet(valid_path, valid_ctx, NULL, strlen(valid_arg));
ASSERT_EQ(res, UMF_RESULT_ERROR_INVALID_ARGUMENT);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have invalid ctx as well? (not sure if this makes sense or not)

auto res = umfPoolCreate(m_poolOps, m_provider, m_params, 0, &m_pool);
if (res != UMF_RESULT_SUCCESS) {
m_pool = nullptr;
LOG_ERR("Failed to create memory pool");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, if you still want to print some error msg in tests you can just use printf or something..


umf_result_t umfCtlExec(const char *name, void *ctx, void *arg, size_t size) {
// arg can be NULL when executing a command
// ctx can be NULL when executing defaults
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ctx can be NULL but you return UMF_RESULT_ERROR_INVALID_ARGUMENT?
additionally, it looks like we don't have a test for this case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, fixed

const char *extra_name,
umf_ctl_query_type_t queryType) {
(void)indexes, (void)source;
if (ctx) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where do you use ctx?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it because the exec can also go through this path

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants